//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <elasys_server.h>

#define USER_ENVIRONMENT_SIZE       0x3000      // 12KB
#define USER_DEVPATH_SIZE           0x2000      // 8KB
#define MAX_ENVIRONMENT_ITEM        127

static void *g_pEnvironBase = NULL;
static void *g_pDevpathBase = NULL;

#define ELASTOS_PATH             "C:\\Program Files\\Elastos"
#define ELASTOS_PATH_L          L"C:\\Program Files\\Elastos"

#define ELASTOS_RESOURCE_PATH    "C:\\Program Files\\Elastos\\Resources"
#define ELASTOS_RESOURCE_PATH_L L"C:\\Program Files\\Elastos\\Resources"

#if defined(_GNUC)
#define ENVIRON(key, path)   key#path
#define ENVIRON_L(key, path) key#path
#elif defined(_MSVC)
#define ENVIRON(key, path)   key##path
#define ENVIRON_L(key, path) key##path
#else
#error unsupported compiler.
#endif

EXTERN_C void  CDECL initenv(wchar_t **);
EXTERN_C ECode PutEnv(const char *, const wchar_t *);

static ECode SetEnviroments(wchar_t **ppwszEnvBase)
{
    ECode ec = NOERROR;

    initenv(ppwszEnvBase);
    ec = PutEnv(ENVIRON("CD=", ELASTOS_PATH),
                ENVIRON(L"CD=", ELASTOS_PATH_L));
    if (FAILED(ec)) return ec;

    ec = PutEnv(ENVIRON("XDK_COMMON_RESOURCES=", ELASTOS_RESOURCE_PATH),
                ENVIRON(L"XDK_COMMON_RESOURCES=", ELASTOS_RESOURCE_PATH_L));
    if (FAILED(ec)) return ec;

    return NOERROR;
}

EXTERN_C ECode Environment_Initialize()
{
    ECode ec = NOERROR;

    g_pEnvironBase = malloc(USER_ENVIRONMENT_SIZE);
    if (NULL == g_pEnvironBase) {
        ec = E_OUT_OF_MEMORY;
        goto E_FAIL_EXIT;
    }
    memset(g_pEnvironBase, 0, USER_ENVIRONMENT_SIZE);

    g_pDevpathBase = malloc(USER_DEVPATH_SIZE);
    if (NULL == g_pDevpathBase) {
        ec = E_OUT_OF_MEMORY;
        goto E_FAIL_EXIT;
    }
    memset(g_pDevpathBase, 0, USER_DEVPATH_SIZE);

    ec = SetEnviroments((wchar_t **)g_pEnvironBase);
    if (FAILED(ec)) {
        goto E_FAIL_EXIT;
    }

    return ec;

E_FAIL_EXIT:
    if (NULL != g_pEnvironBase) {
        free(g_pEnvironBase);
        g_pEnvironBase = NULL;
    }
    if (NULL != g_pDevpathBase) {
        free(g_pDevpathBase);
        g_pDevpathBase = NULL;
    }
    return ec;
}

EXTERN_C void Environment_Destroy()
{
    if (NULL != g_pEnvironBase) {
        free(g_pEnvironBase);
        g_pEnvironBase = NULL;
    }
    if (NULL != g_pDevpathBase) {
        free(g_pDevpathBase);
        g_pDevpathBase = NULL;
    }
}

EXTERN_C void  _GetEnvBase(
        /* [out] */ wchar_t *** pppwszEnvBase,
        /* [out] */ wchar_t **  ppwszDevpath)
{
    assert(NULL != g_pEnvironBase);
    assert(NULL != g_pDevpathBase);

    assert(NULL != pppwszEnvBase);
    assert(NULL != ppwszDevpath);

    *pppwszEnvBase = (wchar_t **)g_pEnvironBase;
    *ppwszDevpath = (wchar_t *)g_pDevpathBase;
}
